import Design from '@/plugins/design/index'

import utils from '@/plugins/utils/utils.js'

const events = ['test', 'console.dev', 'console.log', 'widget-drop-to-canvas', 'drag-canvas', 'widget-created',
  'select-widget',
  'widget-update', 'widget-dblclick', 'widget-focus', 'widget-select', 'widget-blur', 'widget-hover',
  'widget-unhover',
  'key-down', 'key-up', 'widget-move', 'alt-keydown', 'move-canvas'
]

const keymapping = {
  16: 'shift',
  18: 'alt',
  32: 'space'
}

/**
 * https://blog.csdn.net/qq_26963495/article/details/86489063
 */
const removeEvents = function() {
  if (process.client) {
    for (let i in events) {
      $nuxt.$off(events[i])
    }
  }
} // end removeEvents()

let design = null
let designState = null

let $this = this

export default function(context) {
  console.log('design-event-bus start')
  console.log('APP_ENV: ', process.env.APP_ENV)
  if (process.client) {
    // 防止监听一次事件，却多次触发事件方法
    removeEvents()

    $nuxt.$on('init-design', () => {
      design = new Design()
      window.$design = design
      designState = $nuxt.$store.state.design

      context.store.commit('design/setDesignSize', design.config.size)
      console.log('init end...')
    })
    // ============================
    $nuxt.$on('test', (args) => {
      // 测试
      console.log('on test: ', args)
    })
    $nuxt.$on('console.dev', (args) => {
      if (process.env.APP_ENV == 'development') {
        if (!!args.error || !!args.err) {
          console.error(args)
        } else {
          console.log(args)
        }
      }
    })
    $nuxt.$on('console.prod', (args) => {
      if (!!args && !process.env.APP_ENV == 'production') {
        delete args.source
      }
      if (!!args.error || !!args.err) {
        console.error(args)
      } else {
        console.log(args)
      }
    })

    $nuxt.$on('console.log', (args) => {
      if (!!args.error || !!args.err) {
        console.error(args)
      } else {
        console.log(args)
      }
    })



    /**
     * 废弃
     * 拖动画布获取坐标系，移动操作在_id.js#dragDesignHandler(e)方法中
     * args: 当前坐标
     */
    $nuxt.$on('drag-canvas-get-coordinate', (args) => {
      if (!design) {
        $nuxt.$emit('console.prod', {
          err: 'design init error - ',
          source: '@/middleware/design-event-bus.js#$on(drag-canvas, ...)'
        })
      } else {
        design.coordinate = args
        console.log('design.coordinate', design.coordinate)
      }
    })
    /**
     * 拖动画布 - 
     * args: 偏移量:{offetX[,offteY]}。坐标位置：{x,y}
     */
    $nuxt.$on('move-canvas', (args) => {
      if (!args) {
        console.error('move-canvas args error: ', args)
        return false
      }

      // 画布坐标
      let coordinate = null

      if (!!args.x && !!args.y) {
        // 使用坐标移动
        coordinate = {
          x: args.x,
          y: args.y
        }
        // 限制拖动位置大小 - X
        if (design.config.size.widthHalf <= Math.abs(coordinate.x)) {
          coordinate.x = coordinate.x > 0 ? design.config.size.widthHalf : -design.config.size.widthHalf
        }
        // 限制拖动位置大小 - Y
        if (design.config.size.heightHalf <= Math.abs(coordinate.y)) {
          coordinate.y = coordinate.y > 0 ? design.config.size.heightHalf : -design.config.size.heightHalf
        }
        design.coordinate = coordinate
        context.store.commit('design/setTransformxy', coordinate)
        return true
      }

      // 使用偏移量移动
      let offetArgs = null
      if (!!args.offetY && !!args.offetX) {
        // 如果移动了X轴、Y轴
        offetArgs = {
          x: design.coordinate.x + args.offetX,
          y: design.coordinate.y + args.offetY
        }
        // 限制拖动位置大小 - X
        if (design.config.size.widthHalf <= Math.abs(offetArgs.x)) {
          offetArgs.x = offetArgs.x > 0 ? design.config.size.widthHalf : -design.config.size.widthHalf
        }
        // 限制拖动位置大小 - Y
        if (design.config.size.heightHalf <= Math.abs(offetArgs.y)) {
          offetArgs.y = offetArgs.y > 0 ? design.config.size.heightHalf : -design.config.size.heightHalf
        }
      } else if (!!args.offetY) {
        // 如果移动了Y轴
        offetArgs = {
          x: design.coordinate.x,
          y: design.coordinate.y + args.offetY
        }
        // 限制拖动位置大小
        if (design.config.size.heightHalf <= Math.abs(offetArgs.y)) {
          offetArgs.y = offetArgs.y > 0 ? design.config.size.heightHalf : -design.config.size.heightHalf
        }
      } else if (!!args.offetX) {
        // TODO 
        // 如果移动了Y轴
        offetArgs = {
          x: design.coordinate.x + args.offetX,
          y: design.coordinate.y
        }
        // 限制拖动位置大小 - X
        if (design.config.size.widthHalf <= Math.abs(offetArgs.x)) {
          offetArgs.x = offetArgs.x > 0 ? design.config.size.widthHalf : -design.config.size.widthHalf
        }
      }
      if (offetArgs != null) {
        design.coordinate = offetArgs
        // 设置画布偏移量
        context.store.commit('design/setTransformxy', offetArgs)
      }

    })

    // 拖动组件进入画布
    $nuxt.$on('widget-drop-to-canvas', (args) => {
      console.log('on widget-drop-to-canvas', args)
      // 创建组件
      design.createWidget(args)
    })
    // 组件创建成功
    $nuxt.$on('widget-created', (args) => {
      // 创建成功
      // TODO 根据args.code添加class
      args.element.classList.add('xxxxxxx')
    })

    // TODO 双击事件，修改
    $nuxt.$on('widget-dblclick', (_widget) => {
      console.log('双击事件... ...')
    })

    // 更新widget
    $nuxt.$on('widget-update', (args) => {
      design.updateWidget(args)
      // 更新 state.selection
    })

    $nuxt.$on('widget-select', (wid) => {
      // console.log('on widget-select')
      // 选择了widget
      if (!context.store.state.design.keydown.space) {
        // 如果未按下空格键
        context.store.commit('design/selectWidget', wid)
      }

    })

    // 重新计算选中的widget的边框，widget-reset-boder
    $nuxt.$on('widget-reset-boder', () => {
      context.store.commit('design/resetBoder')
    })

    // args: {action:'move', left:'',top:''} 参数是偏移量
    // 使用 left==-1,top==1的方式，如：向右下移动：left:1,top:1
    // 鼠标移动方向 - {left:1向右，-1向左；top：1向下，-1向上}
    // 移动选择的widget

    // 偏移量，>= 0，用户吸附、逃逸中的逃逸功能
    let _offset_left = 0;
    let _offset_top = 0;
    let _xifu = 2; // 2px 进行吸附和逃逸
    $nuxt.$on('widget-move', (args) => {
      // console.log('on widget-move',args.top,args.left)
      // console.log('context.store.state.design: ',design.)
      if (!context.store.state.design.keydown.space) {
        // 如果未按下空格键
        // if (Math.abs(args.top) <= 2 && args.top != 0) {
        //     args.top = args.top > 0 ? 1 : -1
        // }
        // if (Math.abs(args.left) <= 2 && args.left != 0) {
        //     args.left = args.left > 0 ? 1 : -1
        // }
        context.store.commit('design/moving', true)

        // 修改了每个选中的widget的位置
        design.updateWidget(args)


        // 重置边框 handler
        // 【重要】TODO 优化方案，移动widget时不显示边框，鼠标释放时显示
        // TODO 鼠标释放时在进行该操作
        context.store.commit('design/resetBoder')

        // 顺序很重要：重新设置边框 --> 计算参考线
        // TODO 异步/同步：计算参考线（先使用异步）
        // 1、获取当前选中的坐标 state.totalSelect
        // 2、获取剩下其他的widget坐标
        // 3、如何计算？？
        // 3.1、
        // 4、更新参考线（不同类型）
        design.calculationRefLines()
      }
    })

    // 可能要废弃   
    $nuxt.$on('widget-add-select', (wid) => {
      context.store.commit('design/addSelectWidget', wid)
    })
    $nuxt.$on('widget-unselect', (wid) => {
      // 选择了widget
      context.store.commit('design/unselectWidget', wid)
    })
    $nuxt.$on('widget-unselect-all', () => {
      // 选择了widget
      context.store.commit('design/unselectAll')
    })

    // 鼠标移入事件 - hover
    $nuxt.$on('widget-hover', (wid) => {
      context.store.commit('design/hover', wid)
    })
    // 鼠标移出事件 - unhover
    $nuxt.$on('widget-unhover', (wid) => {
      context.store.commit('design/unhover')
    })

    let _hover = $nuxt.$store.state.design.hover
    $nuxt.$on('alt-keydown', () => {
      // 判断alt键是否按下
      // 如果
      if (!$nuxt.$store.state.design.keydown.alt || _hover != $nuxt.$store.state.design.hover) {
        // 当移动到widget上时可以进入判断

        // console.log('按下alt键', $nuxt.$store.state.design.totalSelect)
        // console.log('按下alt键', $nuxt.$store.state.design.hover)
        _hover = $nuxt.$store.state.design.hover
        if ($nuxt.$store.state.design.hover == null) {
          // 画布或本身
          utils.$print('画布')
        } else {
          // 选中widget并且alt时，hover其他widget
          utils.$print('widget', _hover)
        }
      }
    })

    $nuxt.$on('key-down', (key) => {
      let args = {
        key: keymapping[key], // 名称
        value: key // 数字
      }
      context.store.commit('design/setkeydown', args)
    })
    $nuxt.$on('key-up', (key) => {
      context.store.commit('design/removekeydown', keymapping[key])
    })

  }
}
